package task

import (
	"context"
	"fmt"
	"medicine/internal/data"
	"time"

	"medicine/internal/biz"

	"gorm.io/gorm"
)

// StartOrderTimeoutTask 启动订单超时自动取消定时任务
func StartOrderTimeoutTask(dataRepo *data.DataRepo) {
	go func() {
		for {
			time.Sleep(time.Minute)
			cancelTimeoutOrders(dataRepo)
		}
	}()
}

// cancelTimeoutOrders 查找并取消超时未支付订单，回滚库存
func cancelTimeoutOrders(dataRepo *data.DataRepo) {
	ctx := context.Background()
	cutoff := time.Now().Add(-30 * time.Minute)
	var orders []struct{ ID int64 }
	err := dataRepo.DB.Table("seckill_orders").
		Where("status = ? AND created_at < ?", "待支付", cutoff).
		Select("id").Find(&orders).Error
	if err != nil {
		fmt.Printf("[定时任务] 查询超时订单失败: %v\n", err)
		return
	}

	fmt.Printf("[定时任务] 找到 %d 个超时订单需要取消\n", len(orders))

	for _, o := range orders {
		// 使用事务处理，确保订单状态更新和库存回滚的原子性
		err := dataRepo.DB.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
			// 1. 更新订单状态为已取消
			result := tx.Model(&biz.SeckillOrder{}).
				Where("id = ? AND status = ?", o.ID, "待支付").
				Update("status", "已取消")
			if result.Error != nil {
				return fmt.Errorf("更新订单状态失败: %v", result.Error)
			}
			if result.RowsAffected == 0 {
				// 订单可能已经被其他进程处理，跳过
				fmt.Printf("[定时任务] 订单ID=%d 状态已变更，跳过处理\n", o.ID)
				return nil
			}

			// 2. 回滚Redis库存
			if err := dataRepo.RollbackStockForce(ctx, o.ID); err != nil {
				fmt.Printf("[定时任务] 回滚库存失败，订单ID=%d, err=%v\n", o.ID, err)
				// 注意：这里不返回错误，避免事务回滚，因为订单状态已经更新
				// 库存回滚失败可以通过其他机制补偿
			}

			fmt.Printf("[定时任务] 成功取消超时订单并回滚库存: 订单ID=%d\n", o.ID)
			return nil
		})

		if err != nil {
			fmt.Printf("[定时任务] 处理订单ID=%d 失败: %v\n", o.ID, err)
		}
	}
}
